package de.lmu.ifi.pst.uwejsf.framework.process;

import java.util.HashMap;
import java.util.Map;

public abstract class ActivityNode {

	protected ProcessActivityBean activity;

	protected Map<ActivityNode, String> followers = new HashMap<ActivityNode, String>();

	public void addFollower(ActivityNode follower) {
		addFollower(follower, null);
	}

	public void addFollower(ActivityNode follower, String guardExpression) {

		followers.put(follower, guardExpression);
	}

	public ActivityNode getFollower() {
		if (followers.isEmpty())
			return null;
		else if (followers.size() > 1) {
			return chooseFollower();
		} else
			return followers.keySet().iterator().next();

	}

	protected ActivityNode chooseFollower() {
		ActivityNode alternative = null;
		ActivityNode result = null;
		for (ActivityNode activityNode : followers.keySet()) {
			String guardExpression = followers.get(activityNode);
			ActivityGuardHandler.GuardEvaluationResult evaluationResult = activity
					.getGuardHandler().evaluateGuardExpression(guardExpression,
							activity.getObjectStorage());

			if (evaluationResult == ActivityGuardHandler.GuardEvaluationResult.IS_FALLBACK) {
				if (alternative != null)
					throw new IllegalProcessStateException(
							"More than one outgoing control flows has a guard ELSE or no guard.");
				alternative = activityNode;
			} else if (evaluationResult == ActivityGuardHandler.GuardEvaluationResult.TRUE) {
				if (result != null)
					throw new IllegalProcessStateException(
							"More than one outgoing control flows has a guard that evaluates to true.");
				result = activityNode;
			}

		}

		if (result == null)
			return alternative;
		else
			return result;

	}

	public ActivityNode(ProcessActivityBean activity) {
		this.activity = activity;
	}

	public ProcessActivityBean getActivity() {
		return activity;
	}

}
